#include "matrix_btn_driver.h"
#include "gd32f4xx.h"
#include "systick.h"
#include "led_driver.h"
#include <stdio.h>

uint32_t MatrixBtnRowPins[4] = {GPIO_PIN_8, GPIO_PIN_9, GPIO_PIN_10, GPIO_PIN_11};
uint32_t MatrixBtnColPins[4] = {GPIO_PIN_12, GPIO_PIN_13, GPIO_PIN_14, GPIO_PIN_15};

void matrix_btn_driver_config(void)
{
    // 外设时钟使能
    rcu_periph_clock_enable(RCU_GPIOE);

    //
}

// /**
//  * 行做输出,列做输入
//  * 行做供电端,列做受电端
//  * 行高电平
//  */
// void matrix_btn_driver_row_out_col_in(void)
// {
//     size_t row = 0;
//     for (row = 0; row < 4; row++)
//     {
//         gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, MatrixBtnRowPins[row]);
//         gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, MatrixBtnRowPins[row]);
//         gpio_bit_set(GPIOE, MatrixBtnRowPins[row]);
//     }

//     size_t col = 0;
//     for (col = 0; col < 4; col++)
//     {
//         gpio_mode_set(GPIOE, GPIO_MODE_INPUT, GPIO_PUPD_NONE, MatrixBtnColPins[col]);
//     }
// }

// void matrix_btn_driver_row_in_col_out(void)
// {
//     size_t row = 0;
//     for (row = 0; row < 4; row++)
//     {
//         gpio_mode_set(GPIOE, GPIO_MODE_INPUT, GPIO_PUPD_NONE, MatrixBtnRowPins[row]);
//     }

//     size_t col = 0;
//     for (col = 0; col < 4; col++)
//     {
//         gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, MatrixBtnColPins[col]);
//         gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, MatrixBtnColPins[col]);
//         gpio_bit_set(GPIOE, MatrixBtnColPins[col]);
//     }
// }

/**
 * 行做输出,列做输入
 * 行:推挽输出,作为受电端,提供低电平
 * 列:上拉输入,作为供电断,
 *
 */
void matrix_btn_driver_row_out_col_in(void)
{
    uint8_t row;
    uint8_t col;

    for (row = 0; row < 4; row++)
    {
        gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, MatrixBtnRowPins[row]);
        gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, MatrixBtnRowPins[row]);
        gpio_bit_reset(GPIOE, MatrixBtnRowPins[row]);
    }

    for (col = 0; col < 4; col++)
    {
        gpio_mode_set(GPIOE, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, MatrixBtnColPins[col]);
    }
}

void matrix_btn_driver_row_in_col_out(void)
{
    uint8_t row;
    uint8_t col;

    for (row = 0; row < 4; row++)
    {
        gpio_mode_set(GPIOE, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, MatrixBtnRowPins[row]);
    }

    for (col = 0; col < 4; col++)
    {
        gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, MatrixBtnColPins[col]);
        gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, MatrixBtnColPins[col]);
        gpio_bit_reset(GPIOE, MatrixBtnColPins[col]);
    }
}

uint8_t matrix_btn_driver_get_btn_col_status(void)
{
    uint8_t bits = 0;
    size_t i;
    for (i = 0; i < 4; i++)
    {
        uint8_t bit = gpio_input_bit_get(GPIOE, MatrixBtnColPins[i]) == RESET ? 0b1u : 0b0U; // 0表示按钮按下

        bits |= bit << i;
    }

    return bits;
}

uint8_t matrix_btn_driver_get_btn_row_status(void)
{
    uint8_t bits = 0;
    size_t i;
    for (i = 0; i < 4; i++)
    {
        uint8_t bit = gpio_input_bit_get(GPIOE, MatrixBtnRowPins[i]) == RESET ? 0b1u : 0b0U;
        bits |= bit << i;
    }
    return bits;
}

void matrix_btn_driver_get_status(uint8_t *row, uint8_t *col)
{
    uint8_t rowIndex = 0;
    uint8_t colIndex = 0;

    matrix_btn_driver_row_out_col_in();
    colIndex = matrix_btn_driver_get_btn_col_status();

    matrix_btn_driver_row_in_col_out();
    rowIndex = matrix_btn_driver_get_btn_row_status();

    if (colIndex == 0 || rowIndex == 0)
    {
        *row = 0;
        *col = 0;
    }
    else
    {
        *row = rowIndex;
        *col = colIndex;
    }
}

void matrix_btn_driver_test(void)
{
    static uint8_t row = 0U;
    static uint8_t col = 0U;

    matrix_btn_driver_get_status(&row, &col);
    printf("matrix_btn:[%d,%d]\n", row, col);
    //
    //
    if ((row & 0b1u) && (col & 0b1u))
    {
        led_driver_set(0b1u);
    }
    else
    {
        led_driver_all_off();
    }

    delay_1ms(500);
}
